package com.smartrodin.springbootrabbitmq.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.smartrodin.springbootrabbitmq.entity.MqSendFileLog;
import com.smartrodin.springbootrabbitmq.mapper.MqSendFileLogMapper;
import com.smartrodin.springbootrabbitmq.util.Constant;
import com.smartrodin.springbootrabbitmq.util.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * @author: arnold_nie
 * @date: 2020/7/8 14:51
 * FileName: RabbitTemplateConfig
 * Description: 发送消息确认配置
 */
@Slf4j
@Component
public class RabbitTemplateConfig implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private MqSendFileLogMapper mqSendFileLogMapper;

    @PostConstruct
    public void initRabbitTemplate() {
        // 设置生产者消息确认
        rabbitTemplate.setConfirmCallback( this );
        rabbitTemplate.setReturnCallback( this );
    }

    @Override
    public void confirm(@Nullable CorrelationData correlationData, boolean ack, String cause) {
        log.info( "消息唯一标识: {}", correlationData );
        log.info( "确认状态: {}", ack );
        log.info( "造成原因: {}", cause );
        String key = Constant.MESSAGE_SEND_MQ + correlationData.getId();
        if (!ack) {
            String data = (String) redisTemplate.opsForValue().get( key );
            if (StringUtils.isNotBlank( data )) {
                MqSendFileLog fileLog = JSONObject.toJavaObject( JSON.parseObject( data ), MqSendFileLog.class );
                fileLog.setDelFlag( Constant.NUMBER_ONE );
                fileLog.setStatus( Constant.NUMBER_ONE );
                fileLog.setCreateTime( DateUtils.getCurrentDateTime() );
                fileLog.setErrorMsg( cause );
                fileLog.setFailNumber( Constant.NUMBER_ZORE );
                mqSendFileLogMapper.insert( fileLog );
            } else {
                log.error( "redis 获取数据为空，key 为： {}", key );
            }
        }
        redisTemplate.delete( key );
    }

    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        log.info( "消息主体 message : {}", message );
        log.info( "描述：{}", replyText );
        log.info( "消息使用的交换器 exchange : {}", exchange );
        log.info( "消息使用的路由键 routing : {}", routingKey );
        MessageProperties messageProperties = message.getMessageProperties();
        String correlationId = messageProperties.getCorrelationId();
        log.info( "消息 correlationId : {}", correlationId );
        Integer msgSendType = (Integer) messageProperties.getHeaders().get( Constant.MSG_SEND_TYPE );
        MqSendFileLog fileLog = new MqSendFileLog();
        fileLog.setMsgSendType( msgSendType );
        fileLog.setMsg( new String( message.getBody() ) );
        fileLog.setDelFlag( Constant.NUMBER_ONE );
        fileLog.setStatus( Constant.NUMBER_ONE );
        fileLog.setCreateTime( DateUtils.getCurrentDateTime() );
        fileLog.setErrorMsg( replyText );
        fileLog.setFailNumber( Constant.NUMBER_ZORE );
        fileLog.setExchange( exchange );
        fileLog.setRoutingKey( routingKey );
        mqSendFileLogMapper.insert( fileLog );
    }

}
